package demo6

import "fmt"

// 组合设计模式，可以定制不同的组合结构，树形结构
type Component interface {
	//  设置主节点
	Parent() Component
	SetParent(Component)
	// -------------
	// 公用属性
	Name() string
	SetName(string)
	// -------------
	// 设置子节点
	AddChild(Component)
	Print(string)
}

const (
	LeafNode = iota
	CompositeNode
)

func NewComponent(kind int, name string) Component {
	var c Component
	// 根据不同的条件选择不同的实现方法
	switch kind {
	case LeafNode:
		c = NewLeaf() // 实现接口
	case CompositeNode:
		c = NewComposite() // 实现了接口
	}
	c.SetName(name)
	return c
}

// 模板
type component struct {
	parent Component
	name   string
}

func (c *component) Parent() Component {
	return c.parent
}

func (c *component) SetParent(parent Component) {
	c.parent = parent
}

func (c *component) Name() string {
	return c.name
}

func (c *component) SetName(name string) {
	c.name = name
}

func (c *component) AddChild(Component) {}

func (c *component) Print(string) {}

// 继承  分叉节点
type Leaf struct {
	component
}

func NewLeaf() *Leaf {
	return &Leaf{}
}
func (c *Leaf) Print(pre string) {
	fmt.Printf("%s-%s\n", pre, c.Name())
}

// 继承并设置添加子节点到父节点里面 分叉节点
type Composite struct {
	component
	childs []Component
}

func NewComposite() *Composite {
	return &Composite{
		childs: make([]Component, 0),
	}
}
func (c *Composite) AddChild(child Component) {
	child.SetParent(c)
	c.childs = append(c.childs, child)
}

func (c *Composite) Print(pre string) {
	fmt.Printf("%s+%s\n", pre, c.Name())
	pre += " "
	// 遍历所有的节点  当前c 节点是遍历子节点的父级别节点
	for _, comp := range c.childs {
		// 根据不同的对象调用不同的方法
		comp.Print(pre)
	}
}
